//
//  CaseViewController.m
//  CoreAnimation
//
//  Created by m w on 2023/3/10.
//
#define k_SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#define k_LAND_BEGIN_HEIGHT 550 - 20
#import "CaseViewController.h"

@interface CaseViewController ()

@property (weak, nonatomic) IBOutlet UILabel *sun;

@property (weak, nonatomic) IBOutlet UIView *bgV;

@property(strong,nonatomic)CALayer *landLayer;

@property(strong,nonatomic)CAShapeLayer *greenTrack;

@property(strong,nonatomic)CAShapeLayer *yellowTrack;

@property (nonatomic,strong)UILabel *unlockLabel;

@property (weak, nonatomic) IBOutlet UIImageView *feiji;



@end

@implementation CaseViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"过山车🎢";

}

//添加蓝天
- (IBAction)addSky:(id)sender {
    
    [self initBackgroundSky];
}

//添加太阳
- (IBAction)addSun:(id)sender {
    
    self.sun.hidden = NO;
    CABasicAnimation * ani = [CABasicAnimation animationWithKeyPath:@"opacity"];
    ani.toValue = @0;
    ani.removedOnCompletion = NO;
    ani.fillMode = kCAFillModeForwards;
    ani.duration = 0.5;
    ani.repeatCount = HUGE_VALF;
    ani.removedOnCompletion = YES;
    ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.sun.layer addAnimation:ani forKey:@"TranslationAni"];
}

//添加雪山
- (IBAction)addXueShan:(id)sender {
    
    [self xueshan];
}

//山上的绿色
- (IBAction)shancao:(id)sender {
    
    [self shanshangdecao];
}

//地上的草
- (IBAction)xiaocao:(id)sender {
    
    [self initLawn];
}

//土地
- (IBAction)tudi:(id)sender {
    
    [self initLand];
}

//轨道
- (IBAction)guidao:(id)sender {
    [self initYellowTrack];
    [self initGreenTrack];
}
//填充轨道的图片
- (IBAction)tiaotu:(id)sender {
    _yellowTrack.fillColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"yellow"]].CGColor;
    _greenTrack.fillColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"green"]].CGColor;
}

//加小树
- (IBAction)loukong:(id)sender {
    [self initTree];
}

//加白云
- (IBAction)baiyun:(id)sender {
    
    [self initCloudAnimation];
}

- (IBAction)guoshanche:(id)sender {
    //    添加黄色轨道小车动画
    [self carAnimationWith:@"car" TrackLayer:_yellowTrack AnimationDuration:8.0 BeginTime:CACurrentMediaTime() + 1];
    //    添加绿色轨道小车动画
    [self carAnimationWith:@"otherCar" TrackLayer:_greenTrack AnimationDuration:5.0 BeginTime:CACurrentMediaTime()];
}

- (IBAction)feiji:(id)sender {
    
    [self initFeijiAnimation];
}


//初始化背景天空渐变色
- (void)initBackgroundSky{
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = self.bgV.bounds;
    gradientLayer.colors = @[
                             (__bridge id)[UIColor colorWithRed:40.0 / 255.0 green:150.0 / 255.0 blue:200.0 / 255.0 alpha:1.0].CGColor,
                             (__bridge id)[UIColor colorWithRed:255.0 / 255.0 green:250.0 / 255.0 blue:250.0 / 255.0 alpha:1.0].CGColor];

    gradientLayer.locations = @[@0.2,@0.5];
    gradientLayer.startPoint = CGPointMake(0, 0);
    gradientLayer.endPoint = CGPointMake(1, 1);
    [self.view.layer addSublayer:gradientLayer];

    gradientLayer.mask = _bgV.layer;
    [self.view addSubview:_bgV];

    //执行动画 animation
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"locations"];
    animation.fromValue = @[@0,@0];
    animation.toValue = @[@0.25,@0.75];
    animation.repeatCount = 1;
    animation.duration = 1.0f;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    [gradientLayer addAnimation:animation forKey:nil];
}


- (void)shanshangdecao {
    // 开始画山体没有被雪覆盖的部分
    CAShapeLayer *leftSnowbergBody = [[CAShapeLayer alloc] init];
    UIBezierPath *leftSnowbergBodyPath = [[UIBezierPath alloc] init];
    
    //    把bezierpath的起点移动到雪山左下角相同的位置
    CGPoint startPoint = CGPointMake(0, self.bgV.frame.size.height - 120);
    CGPoint endPoint = CGPointMake(100, 100);
    CGPoint firstPathPoint = [self calculateWithXValue:20 startPoint:startPoint endpoint:endPoint];
    [leftSnowbergBodyPath moveToPoint:startPoint];
    
    [leftSnowbergBodyPath addLineToPoint:firstPathPoint];
    [leftSnowbergBodyPath addLineToPoint:CGPointMake(60, firstPathPoint.y)];
    [leftSnowbergBodyPath addLineToPoint:CGPointMake(100, firstPathPoint.y + 30)];
    [leftSnowbergBodyPath addLineToPoint:CGPointMake(140, firstPathPoint.y)];
    [leftSnowbergBodyPath addLineToPoint:CGPointMake(180, firstPathPoint.y - 20)];
    
    CGPoint secondPathPoint = [self calculateWithXValue:(self.bgV.frame.size.width / 2 - 125) startPoint:endPoint endpoint:CGPointMake(self.bgV.frame.size.width / 2, k_LAND_BEGIN_HEIGHT)];
    [leftSnowbergBodyPath addLineToPoint:CGPointMake(secondPathPoint.x - 30, firstPathPoint.y)];
    
    [leftSnowbergBodyPath addLineToPoint:secondPathPoint];
    
    [leftSnowbergBodyPath addLineToPoint:CGPointMake(self.bgV.frame.size.width / 2, k_LAND_BEGIN_HEIGHT)];
    [leftSnowbergBodyPath addLineToPoint:CGPointMake(0, k_LAND_BEGIN_HEIGHT)];
    [leftSnowbergBodyPath closePath];
    
    leftSnowbergBody.path = leftSnowbergBodyPath.CGPath;
    UIColor *snowColor = [UIColor colorWithDisplayP3Red:139.0 /255.0 green:92.0 /255.0 blue:0.0 /255.0 alpha:1.0];
    leftSnowbergBody.fillColor = snowColor.CGColor;
    [self.bgV.layer addSublayer:leftSnowbergBody];
    
    //添加路径动画
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"fillColor"];
    animation.fromValue = (__bridge id _Nullable)([UIColor clearColor].CGColor);
    animation.toValue = (__bridge id _Nullable)([UIColor greenColor].CGColor);
    animation.duration = 1.0f;
    animation.removedOnCompletion = NO;
    animation.fillMode  = kCAFillModeForwards;
    [leftSnowbergBody addAnimation:animation forKey:@"fillColor"];
}

- (void)xueshan {
    
    UIBezierPath *leftSnowbergPath = [[UIBezierPath alloc] init];
    //    把bezierpath的起点移动到雪山左下角
    [leftSnowbergPath moveToPoint:CGPointMake(0, self.bgV.frame.size.height - 120)];
    
    //    画一条线到山顶
    [leftSnowbergPath addLineToPoint:CGPointMake(100, 100)];
    
    //    画一条线到右下角->左下角->闭合
    [leftSnowbergPath addLineToPoint:CGPointMake(self.bgV.frame.size.width / 2, k_LAND_BEGIN_HEIGHT)];
    [leftSnowbergPath addLineToPoint:CGPointMake(0, k_LAND_BEGIN_HEIGHT)];
    [leftSnowbergPath closePath];
    
    CAShapeLayer *animLayer = [CAShapeLayer layer];
    //UIBezierPath提供路径!!!!!!
    animLayer.path = leftSnowbergPath.CGPath;
    animLayer.strokeColor = [UIColor clearColor].CGColor;
    //图形填充颜色
    animLayer.fillColor = [UIColor clearColor].CGColor;
    
    [self.bgV.layer addSublayer:animLayer];
    
    //添加路径动画
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"fillColor"];
    animation.fromValue = (__bridge id _Nullable)([UIColor clearColor].CGColor);
    animation.toValue = (__bridge id _Nullable)([UIColor whiteColor].CGColor);
    animation.duration = 1.0f;
    animation.removedOnCompletion = NO;
    animation.fillMode  = kCAFillModeForwards;
    [animLayer addAnimation:animation forKey:@"fillColor"];
}

//初始化草坪
- (void)initLawn{
    CAShapeLayer *leftLawn = [[CAShapeLayer alloc] init];
    UIBezierPath *leftLawnPath = [[UIBezierPath alloc] init];
    
    CGPoint leftStartPoint = CGPointMake(0, k_LAND_BEGIN_HEIGHT);
    
    [leftLawnPath moveToPoint:leftStartPoint];
    [leftLawnPath addLineToPoint:CGPointMake(0, self.bgV.frame.size.height - 100)];
    
    //    画一个二次贝塞尔曲线
    [leftLawnPath addQuadCurveToPoint:CGPointMake(self.bgV.frame.size.width / 3.0, k_LAND_BEGIN_HEIGHT) controlPoint:CGPointMake(self.bgV.frame.size.width / 5.0, self.bgV.frame.size.height - 100)];
    
    leftLawn.path = leftLawnPath.CGPath;
    leftLawn.fillColor = [UIColor clearColor].CGColor;
    [self.bgV.layer addSublayer:leftLawn];
    
    //添加路径动画
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"fillColor"];
    animation.fromValue = (__bridge id _Nullable)([UIColor clearColor].CGColor);
    animation.toValue = (__bridge id _Nullable)([UIColor colorWithDisplayP3Red:82.0 / 255.0 green:177.0 / 255.0 blue:52.0 / 255.0 alpha:1.0].CGColor);
    animation.duration = 1.0f;
    animation.removedOnCompletion = NO;
    animation.fillMode  = kCAFillModeForwards;
    [leftLawn addAnimation:animation forKey:@"fillColor"];
    
    
    CAShapeLayer *rightLawn = [[CAShapeLayer alloc] init];
    UIBezierPath *rightLawnPath = [[UIBezierPath alloc] init];
    
    [rightLawnPath moveToPoint:leftStartPoint];
    //    画一个二次贝塞尔曲线
    [rightLawnPath addQuadCurveToPoint:CGPointMake(self.bgV.frame.size.width, self.bgV.frame.size.height - 80) controlPoint:CGPointMake(self.bgV.frame.size.width / 2.0, self.bgV.frame.size.height - 100)];
    [rightLawnPath addLineToPoint:CGPointMake(self.bgV.frame.size.width, k_LAND_BEGIN_HEIGHT)];
    
    rightLawn.path = rightLawnPath.CGPath;
    rightLawn.fillColor = [UIColor clearColor].CGColor;
    [self.bgV.layer insertSublayer:rightLawn above:leftLawn];
    
    //添加路径动画
    CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"fillColor"];
    animation2.fromValue = (__bridge id _Nullable)([UIColor clearColor].CGColor);
    animation2.toValue = (__bridge id _Nullable)([UIColor colorWithDisplayP3Red:92.0/255.0 green:195.0/255.0 blue:52.0/255.0 alpha:1.0].CGColor);
    animation2.duration = 1.0f;
    animation2.removedOnCompletion = NO;
    animation2.beginTime = CACurrentMediaTime() + 1;
    animation2.fillMode  = kCAFillModeForwards;
    [rightLawn addAnimation:animation2 forKey:@"fillColor"];
    
}


//初始化土地
- (void)initLand{
    _landLayer = [[CALayer alloc] init];
    _landLayer.frame = CGRectMake(0, k_LAND_BEGIN_HEIGHT, self.bgV.frame.size.width, 20);
    _landLayer.backgroundColor = [UIColor clearColor].CGColor;
    [self.bgV.layer addSublayer:_landLayer];
    
    CABasicAnimation * ani = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
    ani.toValue = (id)[UIColor brownColor].CGColor;
    ani.fillMode = kCAFillModeForwards;
    ani.duration = 1.0;
    ani.removedOnCompletion = NO;
    ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [_landLayer addAnimation:ani forKey:@"backgroundColor"];
    
}

//初始化黄色轨道
- (void)initYellowTrack{
    
    _yellowTrack = [[CAShapeLayer alloc] init];
    _yellowTrack.lineWidth = 5;
    _yellowTrack.strokeColor = [UIColor colorWithDisplayP3Red:210.0 / 255.0 green:179.0 / 255.0 blue:54.0 / 255.0 alpha:1.0].CGColor;
    _yellowTrack.fillColor = [UIColor clearColor].CGColor;
    
    UIBezierPath *trackPath = [[UIBezierPath alloc] init];
    //    画一个三次贝塞尔曲线+一个二次贝塞尔曲线
    //    左侧两个拐弯的三次贝塞尔曲线
    [trackPath moveToPoint:CGPointMake(0, self.bgV.frame.size.height - 60)];
    [trackPath addCurveToPoint:CGPointMake(self.bgV.frame.size.width / 1.5, self.bgV.frame.size.height / 2.0 - 20) controlPoint1:CGPointMake(self.bgV.frame.size.width / 6.0, self.bgV.frame.size.height - 200) controlPoint2:CGPointMake(self.bgV.frame.size.width / 3.0, self.bgV.frame.size.height + 50)];
//    //    右侧一个弯度的二次贝塞尔曲线
    [trackPath addQuadCurveToPoint:CGPointMake(self.bgV.frame.size.width + 50, self.bgV.frame.size.height / 3.0) controlPoint:CGPointMake(self.bgV.frame.size.width - 100, 50)];

    [trackPath addLineToPoint:CGPointMake(self.bgV.frame.size.width + 10, self.bgV.frame.size.height + 10)];
    [trackPath addLineToPoint:CGPointMake(0, self.bgV.frame.size.height + 10)];
    
    _yellowTrack.path = trackPath.CGPath;
    [self.view.layer insertSublayer:_yellowTrack below:_landLayer];
    
    //    为了能够让弧线更好看一点，需要加入镂空的虚线
    CAShapeLayer *trackLine = [[CAShapeLayer alloc] init];
    trackLine.lineCap = kCALineCapRound;
    trackLine.strokeColor = [UIColor whiteColor].CGColor;

    trackLine.lineDashPattern = @[@1.0,@6.0];
    trackLine.lineWidth = 2.5;
    trackLine.fillColor = [UIColor clearColor].CGColor;
    trackLine.path = trackPath.CGPath;
    [_yellowTrack addSublayer:trackLine];
    
}

//初始化绿色轨道
- (void)initGreenTrack{
    _greenTrack = [[CAShapeLayer alloc] init];
    _greenTrack.lineWidth = 5;
    _greenTrack.strokeColor = [UIColor colorWithDisplayP3Red:0.0 / 255.0 green:147.0 / 255.0 blue:163.0 /255.0  alpha:1.0].CGColor;
    _greenTrack.fillColor = [UIColor clearColor].CGColor;
    
    //    绿色铁轨的火车从右侧进入，所以从右侧开始绘画。需要画三条曲线，右边一条+中间的圆圈+左边一条
    UIBezierPath *path = [[UIBezierPath alloc] init];
    [path moveToPoint:CGPointMake(self.bgV.frame.size.width + 10, k_LAND_BEGIN_HEIGHT)];
    [path addLineToPoint:CGPointMake(self.bgV.frame.size.width + 10, self.bgV.frame.size.height - 70)];
    [path addQuadCurveToPoint:CGPointMake(self.bgV.frame.size.width / 1.5, self.bgV.frame.size.height - 70) controlPoint:CGPointMake(self.bgV.frame.size.width - 150, 200)];
    
    //    画圆圈
    [path addArcWithCenter:CGPointMake(self.bgV.frame.size.width / 1.6, self.bgV.frame.size.height - 140) radius:70 startAngle:M_PI_2 endAngle:2.5 * M_PI clockwise:YES];
    
    [path addCurveToPoint:CGPointMake(0, self.bgV.frame.size.height - 100) controlPoint1:CGPointMake(self.bgV.frame.size.width / 1.8 - 60, self.bgV.frame.size.height - 60) controlPoint2:CGPointMake(150, self.bgV.frame.size.height / 2.3)];
    
    [path addLineToPoint:CGPointMake(- 10, k_LAND_BEGIN_HEIGHT)];
    _greenTrack.path = path.CGPath;
    

    [self.view.layer addSublayer:_greenTrack];
    
    //    为了能够让弧线更好看一点，需要加入镂空的虚线
    CAShapeLayer *trackLine = [[CAShapeLayer alloc] init];
    trackLine.lineCap = kCALineCapRound;
    trackLine.strokeColor = [UIColor whiteColor].CGColor;

    trackLine.lineDashPattern = @[@1.0,@6.0];
    trackLine.lineWidth = 2.5;
    trackLine.fillColor = [UIColor clearColor].CGColor;
    trackLine.path = path.CGPath;
    [_greenTrack addSublayer:trackLine];
}

//添加点缀的小树
- (void)initTree{
    
    [self addXueshanTreesWithNumber:2 treeFrame:CGRectMake(0, k_LAND_BEGIN_HEIGHT - 300, 13*3, 23*3)];
}

- (void)addXueshanTreesWithNumber:(NSInteger)treesNumber treeFrame:(CGRect)frame{
    UIImage *tree = [UIImage imageNamed:@"tree"];
    for (NSInteger i = 0; i < treesNumber + 1; i++) {
        CALayer *treeLayer = [[CALayer alloc] init];
        treeLayer.contents = (__bridge id _Nullable)(tree.CGImage);
        treeLayer.frame = CGRectMake(120 * i * 0.5 + 60, frame.origin.y, frame.size.width, frame.size.height);
        [self.view.layer insertSublayer:treeLayer above:_greenTrack];
        
        [self makeShakeAnimation:treeLayer];
    }
}

////添加小树
- (void)addTreesWithNumber:(NSInteger)treesNumber treeFrame:(CGRect)frame{
    UIImage *tree = [UIImage imageNamed:@"tree"];
    for (NSInteger i = 0; i < treesNumber + 1; i++) {
        CALayer *treeLayer = [[CALayer alloc] init];
        treeLayer.contents = (__bridge id _Nullable)(tree.CGImage);
        treeLayer.frame = CGRectMake(self.bgV.frame.size.width - 50 * i * (arc4random_uniform(4) + 1), frame.origin.y, frame.size.width, frame.size.height);
        [self.view.layer insertSublayer:treeLayer above:_greenTrack];
    }
}

//抖动动画
-(void)makeShakeAnimation:(CALayer *)layer {
    CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
    NSValue *value_0 = [NSNumber numberWithFloat:-M_PI/180*4];
    NSValue *value_1 = [NSNumber numberWithFloat:M_PI/180*4];
    NSValue *value_3 = [NSNumber numberWithFloat:-M_PI/180*4];
    anima.values = @[value_0,value_1,value_3];
    anima.repeatCount = MAXFLOAT;
    [layer addAnimation:anima forKey:@"shakeAnimation"];
}

//云彩的动画
- (void)initCloudAnimation{
    CALayer *cloud = [[CALayer alloc]init];
    cloud.contents = (__bridge id _Nullable)([UIImage imageNamed:@"cloud"].CGImage);
    cloud.frame = CGRectMake(0, 0, 63, 20);
    [self.view.layer addSublayer:cloud];
    
    UIBezierPath *cloudPath = [[UIBezierPath alloc] init];
    [cloudPath moveToPoint:CGPointMake(self.bgV.frame.size.width + 63, 80)];
    [cloudPath addLineToPoint:CGPointMake(-63, 80)];
    
    CAKeyframeAnimation *ani = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    ani.path = cloudPath.CGPath;
    ani.duration = 5;
    ani.autoreverses = NO;
    ani.repeatCount = CGFLOAT_MAX;
    ani.calculationMode = kCAAnimationPaced;
    [cloud addAnimation:ani forKey:@"position"];
}


//飞机
- (void)initFeijiAnimation{
    CALayer *cloud = [[CALayer alloc]init];
    cloud.contents = (__bridge id _Nullable)([UIImage imageNamed:@"飞机"].CGImage);
    cloud.frame = CGRectMake(0, 0, 80, 80);
    [self.view.layer addSublayer:cloud];
    
    UIBezierPath *cloudPath = [[UIBezierPath alloc] init];
    [cloudPath moveToPoint:CGPointMake(-80, 100)];
    [cloudPath addLineToPoint:CGPointMake(self.bgV.frame.size.width + 80, 100)];
    
    CAKeyframeAnimation *ani = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    ani.path = cloudPath.CGPath;
    ani.duration = 5;
    ani.autoreverses = NO;
    ani.repeatCount = CGFLOAT_MAX;
    ani.calculationMode = kCAAnimationPaced;
    [cloud addAnimation:ani forKey:@"position"];
    
    CALayer *zhadan = [[CALayer alloc]init];
    zhadan.contents = (__bridge id _Nullable)([UIImage imageNamed:@"炸弹"].CGImage);
    zhadan.frame = CGRectMake(0, 0, 40, 40);
    [self.view.layer addSublayer:zhadan];
    
    UIBezierPath *cloudPath1 = [[UIBezierPath alloc] init];
    [cloudPath1 moveToPoint:CGPointMake(40, 100+40)];
    [cloudPath1 addLineToPoint:CGPointMake(400, 400)];
    
    CAKeyframeAnimation *ani1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    ani1.path = cloudPath1.CGPath;
    ani1.duration = 5;
    ani1.beginTime = CACurrentMediaTime() + 0.5;
    ani1.autoreverses = NO;
    ani1.repeatCount = CGFLOAT_MAX;
    ani1.calculationMode = kCAAnimationPaced;
    [zhadan addAnimation:ani1 forKey:@"position"];
}

//抽取过山车的动画
- (CAKeyframeAnimation *)carAnimationWith:(NSString *)carImageName TrackLayer:(CAShapeLayer *)track AnimationDuration:(CFTimeInterval)duration BeginTime:(CFTimeInterval)beginTime {
    CALayer *car = [[CALayer alloc] init];
    car.frame = CGRectMake(0, 0, 22, 15);
    car.contents = (__bridge id _Nullable)([UIImage imageNamed:carImageName].CGImage);
    
    CAKeyframeAnimation *ani = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    ani.path = track.path;
    ani.duration = duration;
    ani.beginTime = beginTime;
    ani.autoreverses = NO;
    ani.repeatCount = CGFLOAT_MAX;
    ani.calculationMode = kCAAnimationPaced;
    ani.rotationMode = kCAAnimationRotateAuto;
    
    [track addSublayer:car];
    [car addAnimation:ani forKey:@"carAni"];
    
    return ani;
}

//根据起始点，算出指定的x在这条线段上对应的y。返回这个point。知道两点，根据两点坐标，求出两点连线的斜率。y=kx+b求出点坐标。
- (CGPoint)calculateWithXValue:(CGFloat)xvalue startPoint:(CGPoint)startPoint endpoint:(CGPoint)endpoint{
    //    求出两点连线的斜率
    CGFloat k = (endpoint.y - startPoint.y) / (endpoint.x - startPoint.x);
    CGFloat b = startPoint.y - startPoint.x * k;
    CGFloat yvalue = k * xvalue + b;
    return CGPointMake(xvalue, yvalue);
}





@end
